package com.ruoyi.pingan.fymodule.goodsinfo.goodscategory.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.ruoyi.pingan.enums.CommonSortOrderEnum;
import com.ruoyi.pingan.exception.CommonException;
import com.ruoyi.pingan.fymodule.goodsinfo.goodscategory.entity.SxoGoodsCategory;
import com.ruoyi.pingan.fymodule.goodsinfo.goodscategory.mapper.SxoGoodsCategoryMapper;
import com.ruoyi.pingan.fymodule.goodsinfo.goodscategory.param.SxoGoodsCategoryAddParam;
import com.ruoyi.pingan.fymodule.goodsinfo.goodscategory.param.SxoGoodsCategoryEditParam;
import com.ruoyi.pingan.fymodule.goodsinfo.goodscategory.param.SxoGoodsCategoryIdParam;
import com.ruoyi.pingan.fymodule.goodsinfo.goodscategory.param.SxoGoodsCategoryPageParam;
import com.ruoyi.pingan.fymodule.goodsinfo.goodscategory.service.SxoGoodsCategoryService;
import com.ruoyi.pingan.page.CommonPageRequest;
import com.ruoyi.pingan.util.CommonDownloadUtil;
import com.ruoyi.pingan.util.CommonResponseUtil;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;


import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * 商品分类Service接口实现类
 *
 * @author wangy
 * @date  2025/07/25 16:46
 **/
@Service
public class SxoGoodsCategoryServiceImpl extends ServiceImpl<SxoGoodsCategoryMapper, SxoGoodsCategory> implements SxoGoodsCategoryService {

    @Override
    public Page<SxoGoodsCategory> page(SxoGoodsCategoryPageParam sxoGoodsCategoryPageParam) {
        QueryWrapper<SxoGoodsCategory> queryWrapper = new QueryWrapper<SxoGoodsCategory>().checkSqlInjection();
        if(ObjectUtil.isAllNotEmpty(sxoGoodsCategoryPageParam.getSortField(), sxoGoodsCategoryPageParam.getSortOrder())) {
            CommonSortOrderEnum.validate(sxoGoodsCategoryPageParam.getSortOrder());
            queryWrapper.orderBy(true, sxoGoodsCategoryPageParam.getSortOrder().equals(CommonSortOrderEnum.ASC.getValue()),
                    StrUtil.toUnderlineCase(sxoGoodsCategoryPageParam.getSortField()));
        } else {
            queryWrapper.lambda().orderByAsc(SxoGoodsCategory::getId);
        }
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(SxoGoodsCategoryAddParam sxoGoodsCategoryAddParam) {
        SxoGoodsCategory sxoGoodsCategory = BeanUtil.toBean(sxoGoodsCategoryAddParam, SxoGoodsCategory.class);
        this.save(sxoGoodsCategory);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(SxoGoodsCategoryEditParam sxoGoodsCategoryEditParam) {
        SxoGoodsCategory sxoGoodsCategory = this.queryEntity(sxoGoodsCategoryEditParam.getId());
        BeanUtil.copyProperties(sxoGoodsCategoryEditParam, sxoGoodsCategory);
        this.updateById(sxoGoodsCategory);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<SxoGoodsCategoryIdParam> sxoGoodsCategoryIdParamList) {
        // 执行删除
        this.removeByIds(CollStreamUtil.toList(sxoGoodsCategoryIdParamList, SxoGoodsCategoryIdParam::getId));
    }

    @Override
    public SxoGoodsCategory detail(SxoGoodsCategoryIdParam sxoGoodsCategoryIdParam) {
        return this.queryEntity(sxoGoodsCategoryIdParam.getId());
    }

    @Override
    public SxoGoodsCategory queryEntity(String id) {
        SxoGoodsCategory sxoGoodsCategory = this.getById(id);
        if(ObjectUtil.isEmpty(sxoGoodsCategory)) {
            throw new CommonException("商品分类不存在，id值为：{}", id);
        }
        return sxoGoodsCategory;
    }

    @Override
    public void downloadImportTemplate(HttpServletResponse response) throws IOException {
       File tempFile = null;
       try {
         List<SxoGoodsCategoryEditParam> dataList = CollectionUtil.newArrayList();
         String fileName = "商品分类导入模板_" + DateUtil.format(DateTime.now(), DatePattern.PURE_DATETIME_PATTERN) + ".xlsx";
         tempFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
         EasyExcel.write(tempFile.getPath(), SxoGoodsCategoryEditParam.class).sheet("商品分类").doWrite(dataList);
         CommonDownloadUtil.download(tempFile, response);
       } catch (Exception e) {
         log.error(">>> 商品分类导入模板下载失败：", e);
         CommonResponseUtil.renderError(response, "商品分类导入模板下载失败");
       } finally {
         FileUtil.del(tempFile);
       }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public JSONObject importData(MultipartFile file) {
        try {
            int successCount = 0;
            int errorCount = 0;
            JSONArray errorDetail = JSONUtil.createArray();
            // 创建临时文件
            File tempFile = FileUtil.writeBytes(file.getBytes(), FileUtil.file(FileUtil.getTmpDir() +
                    FileUtil.FILE_SEPARATOR + "sxoGoodsCategoryImportTemplate.xlsx"));
            // 读取excel
            List<SxoGoodsCategoryEditParam> sxoGoodsCategoryEditParamList =  EasyExcel.read(tempFile).head(SxoGoodsCategoryEditParam.class).sheet()
                    .headRowNumber(1).doReadSync();
            List<SxoGoodsCategory> allDataList = this.list();
            for (int i = 0; i < sxoGoodsCategoryEditParamList.size(); i++) {
                JSONObject jsonObject = this.doImport(allDataList, sxoGoodsCategoryEditParamList.get(i), i);
                if(jsonObject.getBool("success")) {
                    successCount += 1;
                } else {
                    errorCount += 1;
                    errorDetail.add(jsonObject);
                }
            }
            return JSONUtil.createObj()
                    .set("totalCount", sxoGoodsCategoryEditParamList.size())
                    .set("successCount", successCount)
                    .set("errorCount", errorCount)
                    .set("errorDetail", errorDetail);
        } catch (Exception e) {
            log.error(">>> 商品分类导入失败：", e);
            throw new CommonException("商品分类导入失败");
        }
    }

    public JSONObject doImport(List<SxoGoodsCategory> allDataList, SxoGoodsCategoryEditParam sxoGoodsCategoryEditParam, int i) {
        String id = sxoGoodsCategoryEditParam.getId();
        if(ObjectUtil.hasEmpty(id)) {
            return JSONUtil.createObj().set("index", i + 1).set("success", false).set("msg", "必填字段存在空值");
        } else {
            try {
                int index = CollStreamUtil.toList(allDataList, SxoGoodsCategory::getId).indexOf(sxoGoodsCategoryEditParam.getId());
                SxoGoodsCategory sxoGoodsCategory;
                boolean isAdd = false;
                if(index == -1) {
                    isAdd = true;
                    sxoGoodsCategory = new SxoGoodsCategory();
                } else {
                    sxoGoodsCategory = allDataList.get(index);
                }
                BeanUtil.copyProperties(sxoGoodsCategoryEditParam, sxoGoodsCategory);
                if(isAdd) {
                    allDataList.add(sxoGoodsCategory);
                } else {
                    allDataList.remove(index);
                    allDataList.add(index, sxoGoodsCategory);
                }
                this.saveOrUpdate(sxoGoodsCategory);
                return JSONUtil.createObj().set("success", true);
            } catch (Exception e) {
              log.error(">>> 数据导入异常：", e);
              return JSONUtil.createObj().set("success", false).set("index", i + 1).set("msg", "数据导入异常");
            }
        }
    }



    @Override
    public void exportData(List<SxoGoodsCategoryIdParam> sxoGoodsCategoryIdParamList, HttpServletResponse response) throws IOException {
       File tempFile = null;
       try {
         List<SxoGoodsCategoryEditParam> dataList;
         if(ObjectUtil.isNotEmpty(sxoGoodsCategoryIdParamList)) {
            List<String> idList = CollStreamUtil.toList(sxoGoodsCategoryIdParamList, SxoGoodsCategoryIdParam::getId);
            dataList = BeanUtil.copyToList(this.listByIds(idList), SxoGoodsCategoryEditParam.class);
         } else {
            dataList = BeanUtil.copyToList(this.list(), SxoGoodsCategoryEditParam.class);
         }
         String fileName = "商品分类_" + DateUtil.format(DateTime.now(), DatePattern.PURE_DATETIME_PATTERN) + ".xlsx";
         tempFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
         EasyExcel.write(tempFile.getPath(), SxoGoodsCategoryEditParam.class).sheet("商品分类").doWrite(dataList);
         CommonDownloadUtil.download(tempFile, response);
       } catch (Exception e) {
         log.error(">>> 商品分类导出失败：", e);
         CommonResponseUtil.renderError(response, "商品分类导出失败");
       } finally {
         FileUtil.del(tempFile);
       }
    }
}
